package net.goutalk.glcs.module.oa.utils;

import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.mail.MailAccount;
import cn.hutool.extra.mail.MailUtil;
import cn.hutool.extra.spring.SpringUtil;
import net.goutalk.glcs.common.constant.GlobalConstant;
import net.goutalk.glcs.common.enums.MessageType;
import net.goutalk.glcs.common.enums.YesOrNoEnum;
import net.goutalk.glcs.common.sms.SmsSender;
import net.goutalk.glcs.common.utils.RedisUtil;
import net.goutalk.glcs.module.oa.entity.Message;
import net.goutalk.glcs.module.oa.service.IMessageService;
import net.goutalk.glcs.module.organization.entity.User;
import net.goutalk.glcs.module.organization.service.IUserService;
import net.goutalk.glcs.module.workflow.model.NoticePolicyParam;
import lombok.extern.slf4j.Slf4j;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 发送信息工具类
 *
 * @Author: tanyujie
 * @Date: 2022/10/26 16:59
 */
@Slf4j
public class SendMessageUtil {

    public static final String SCHEDULE_CONTENT_TEMPLATE = "您有一则新的日程《{}》,请及时查看.";

    public static final String WORKFLOW_APPROVE_TEMPLATE = "《{}》等待审批。";


    public static final String WORKFLOW_CIRULATED_TEMPLATE = "《{}》等待查看。";

    public static final String WORKFLOW_TIMEOUT_TEMPLATE = "《{}》任务已超时,等待审批。";


    /**
     * 添加日程消息
     */
    public static void sendScheduleMessage(Long userId, String objectId, String title) {
        IMessageService messageService = SpringUtil.getBean(IMessageService.class);

        Message message = new Message();
        message.setMessageType(MessageType.SCHEDULE.getCode());
        message.setSendTime(LocalDateTime.now());
        message.setIsRead(YesOrNoEnum.NO.getCode());
        message.setUserId(userId);
        message.setObjectId(objectId);
        message.setMessageContent(StrUtil.format(SCHEDULE_CONTENT_TEMPLATE, title));

        messageService.save(message);
    }

    /**
     * 添加工作流审批消息
     */
    public static void sendWorkflowApproveMessage(NoticePolicyParam param) {
        IMessageService messageService = SpringUtil.getBean(IMessageService.class);

        List<Message> messageList = new ArrayList<>();
        for (Long userId : param.getNoticeUserIds()) {
            Message message = new Message();
            message.setMessageType(MessageType.APPROVE.getCode());
            message.setSendTime(LocalDateTime.now());
            message.setIsRead(YesOrNoEnum.NO.getCode());
            message.setUserId(userId);
            message.setObjectId(param.getTaskId());
            message.setMessageContent(StrUtil.format(WORKFLOW_APPROVE_TEMPLATE, param.getTaskName()));
            message.setProcessId(param.getProcessId());
            message.setSchemaId(param.getSchemaId());

            messageList.add(message);
        }

        messageService.saveBatch(messageList);
    }


    /**
     * 发送工作流审批短信
     */
    public static void sendWorkflowApproveSms(NoticePolicyParam param, String name) {
        IUserService userService = SpringUtil.getBean(IUserService.class);
        RedisUtil redisUtil = SpringUtil.getBean(RedisUtil.class);

        SmsSender smsSender = SpringUtil.getBean(SmsSender.class);

        //获取用户相关信息
        List<User> userList = redisUtil.get(GlobalConstant.USER_CACHE_KEY, new TypeReference<List<User>>() {
        });
        //如果缓存中不存在用户信息，就直接去数据库查询,并保存到缓存中去
        if (userList.size() == 0) {
            userList = userService.list();
            redisUtil.set(GlobalConstant.USER_CACHE_KEY, userList);
        }
        //构造短信参数，调用短信服务进行短信发送
        if (param.getNoticeUserIds().size() > 0) {
            //获取用户id对应的手机号，用户名
            for (Long userId : param.getNoticeUserIds()) {
                User user = userList.stream().filter(u -> userId.equals(u.getId())).findFirst().orElse(new User());
                String mobile = user.getMobile();
                //调用短信接口服务
                smsSender.sendTimeout(mobile, name);
            }
        }
    }


    /**
     * 添加工作流传阅消息
     */
    public static void sendWorkflowCirculatedMessage(NoticePolicyParam param) {
        IMessageService messageService = SpringUtil.getBean(IMessageService.class);

        List<Message> messageList = new ArrayList<>();
        for (Long userId : param.getNoticeUserIds()) {
            Message message = new Message();
            message.setMessageType(MessageType.CIRCULATED.getCode());
            message.setSendTime(LocalDateTime.now());
            message.setIsRead(YesOrNoEnum.NO.getCode());
            message.setUserId(userId);
            message.setObjectId(param.getTaskId());
            message.setMessageContent(StrUtil.format(WORKFLOW_CIRULATED_TEMPLATE, param.getTaskName()));
            message.setProcessId(param.getProcessId());
            message.setSchemaId(param.getSchemaId());
            messageList.add(message);
        }

        messageService.saveBatch(messageList);
    }

    /**
     * 发送工作流传阅短信
     */
    public static void sendWorkflowCirculatedSms(NoticePolicyParam param, String name) {
        IUserService userService = SpringUtil.getBean(IUserService.class);
        RedisUtil redisUtil = SpringUtil.getBean(RedisUtil.class);

        SmsSender smsSender = SpringUtil.getBean(SmsSender.class);

        //获取用户相关信息
        List<User> userList = redisUtil.get(GlobalConstant.USER_CACHE_KEY, new TypeReference<List<User>>() {
        });
        //如果缓存中不存在用户信息，就直接去数据库查询,并保存到缓存中去
        if (userList.size() == 0) {
            userList = userService.list();
            redisUtil.set(GlobalConstant.USER_CACHE_KEY, userList);
        }
        //构造短信参数，调用短信服务进行短信发送
        if (param.getNoticeUserIds().size() > 0) {
            //获取用户id对应的手机号，用户名
            for (Long userId : param.getNoticeUserIds()) {
                User user = userList.stream().filter(u -> userId.equals(u.getId())).findFirst().orElse(new User());
                String mobile = user.getMobile();
//                //构建参数,您有一个 %s - %s 创建的《%s》任务已超时,请及时处理.StrUtil.format():使用占位符进行替换
//                String text = StrUtil.format(SendMessageUtil.WORKFLOW_TIMEOUT_TEMPLATE, param.getStartUserName(), LocalDateTime.now().format(DateTimeFormatter.ofPattern(GlobalConstant.YYYY_MM_DD_HH_MM_SS_24)), param.getSchemaName());
                //调用短信接口服务
                smsSender.sendCirculated(mobile, name);
            }
        }
    }


    /**
     * 添加工作流超时
     */
    public static void sendWorkflowTimeoutMessage(NoticePolicyParam param) {
        IMessageService messageService = SpringUtil.getBean(IMessageService.class);

        List<Message> messageList = new ArrayList<>();
        for (Long userId : param.getNoticeUserIds()) {
            Message message = new Message();
            //将超时提醒显示在工作流审批消息中
            message.setMessageType(MessageType.APPROVE.getCode());
            message.setSendTime(LocalDateTime.now());
            message.setIsRead(YesOrNoEnum.NO.getCode());
            message.setUserId(userId);
            message.setObjectId(param.getTaskId());
            String format = StrUtil.format(WORKFLOW_TIMEOUT_TEMPLATE, param.getTaskName());
            message.setMessageContent(format);
            message.setProcessId(param.getProcessId());
            message.setSchemaId(param.getSchemaId());
            messageList.add(message);
        }

        messageService.saveBatch(messageList);
    }

    /**
     * 添加工作流超时短信提醒服务
     */
    public static void sendWorkflowTimeoutSms(NoticePolicyParam param, String name) {
        IUserService userService = SpringUtil.getBean(IUserService.class);
        RedisUtil redisUtil = SpringUtil.getBean(RedisUtil.class);

        SmsSender smsSender = SpringUtil.getBean(SmsSender.class);

        //获取用户相关信息
        List<User> userList = redisUtil.get(GlobalConstant.USER_CACHE_KEY, new TypeReference<List<User>>() {
        });
        //如果缓存中不存在用户信息，就直接去数据库查询,并保存到缓存中去
        if (userList.size() == 0) {
            userList = userService.list();
            redisUtil.set(GlobalConstant.USER_CACHE_KEY, userList);
        }
        //构造短信参数，调用短信服务进行短信发送
        if (param.getNoticeUserIds().size() > 0) {
            //获取用户id对应的手机号，用户名
            for (Long userId : param.getNoticeUserIds()) {
                User user = userList.stream().filter(u -> userId.equals(u.getId())).findFirst().orElse(new User());
                String mobile = user.getMobile();
//                //构建参数,您有一个 %s - %s 创建的《%s》任务已超时,请及时处理.StrUtil.format():使用占位符进行替换
//                String text = StrUtil.format(SendMessageUtil.WORKFLOW_TIMEOUT_TEMPLATE, param.getStartUserName(), LocalDateTime.now().format(DateTimeFormatter.ofPattern(GlobalConstant.YYYY_MM_DD_HH_MM_SS_24)), param.getSchemaName());
                //调用短信接口服务
                smsSender.sendTimeout(mobile, name);
            }
        }
    }


    /**
     * 添加工作流超时 断行
     */
    public static void sendWorkflowTimeoutEmail(NoticePolicyParam param) {
        MailAccount mailAccount = SpringUtil.getBean(MailAccount.class);
        RedisUtil redisUtil = SpringUtil.getBean(RedisUtil.class);


        //获取到需要提醒的人员
        List<User> allUser = redisUtil.get(GlobalConstant.USER_CACHE_KEY, new TypeReference<List<User>>() {
        });

        List<String> allEmail = allUser.stream().filter(u -> param.getNoticeUserIds().contains(u.getId())).map(User::getEmail).collect(Collectors.toList());

        String content = StrUtil.format(SendMessageUtil.WORKFLOW_TIMEOUT_TEMPLATE, param.getStartUserName(), LocalDateTime.now().format(DateTimeFormatter.ofPattern(GlobalConstant.YYYY_MM_DD_HH_MM_SS_24)), param.getSchemaName());
        MailUtil.send(mailAccount, allEmail, "超时消息提醒", content, false);

    }


    /**
     * 添加工作流超时 断行
     */
    public static void sendWorkflowApproveEmail(NoticePolicyParam param) {
        MailAccount mailAccount = SpringUtil.getBean(MailAccount.class);
        RedisUtil redisUtil = SpringUtil.getBean(RedisUtil.class);


        //获取到需要提醒的人员
        List<User> allUser = redisUtil.get(GlobalConstant.USER_CACHE_KEY, new TypeReference<List<User>>() {
        });

        List<String> allEmail = allUser.stream().filter(u -> param.getNoticeUserIds().contains(u.getId())).map(User::getEmail).collect(Collectors.toList());

        String content = StrUtil.format(SendMessageUtil.WORKFLOW_TIMEOUT_TEMPLATE, param.getStartUserName(), LocalDateTime.now().format(DateTimeFormatter.ofPattern(GlobalConstant.YYYY_MM_DD_HH_MM_SS_24)), param.getSchemaName());
        MailUtil.send(mailAccount, allEmail, "用户审批", content, false);
    }

    /**
     * 添加工作流超时 断行
     */
    public static void sendWorkflowCirculatedEmail(NoticePolicyParam param) {
        MailAccount mailAccount = SpringUtil.getBean(MailAccount.class);
        RedisUtil redisUtil = SpringUtil.getBean(RedisUtil.class);


        //获取到需要提醒的人员
        List<User> allUser = redisUtil.get(GlobalConstant.USER_CACHE_KEY, new TypeReference<List<User>>() {
        });

        List<String> allEmail = allUser.stream().filter(u -> param.getNoticeUserIds().contains(u.getId())).map(User::getEmail).collect(Collectors.toList());

        String content = StrUtil.format(SendMessageUtil.WORKFLOW_TIMEOUT_TEMPLATE, param.getStartUserName(), LocalDateTime.now().format(DateTimeFormatter.ofPattern(GlobalConstant.YYYY_MM_DD_HH_MM_SS_24)), param.getSchemaName());
        MailUtil.send(mailAccount, allEmail, "用户传阅", content, false);
    }
}
